import pool from './db'
import { session } from 'electron'
import { sanitizeData, createToken } from './common'
const md5 = require('md5');

/**
 * * 创建账户
 *
 * @param {string} name 账户名称
 * @param {number} amount 金额
 * @param {number} assetId 资源ID
 * @param {number} categoryId 分类ID
 * @param {string} notes 备注
 * @param {number} totalAmount 总额度
 * @param {number} billDate 账单日
 * @param {number} dueDate 还款日
 * @author Colin
 */
export const fetchCreateAccount = async function(params) {
  return new Promise(async (resolve, reject) => {
    const { name, amount = 0.00, assetId, categoryId, notes, totalAmount, billDate, dueDate } = params
    const { userId } = this

    try {
      const [result] = await pool.execute(
        `INSERT INTO accounts (userId, assetId, categoryId, name, amount, notes, totalAmount, billDate, dueDate)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [userId, assetId, categoryId, name, amount || 0.00, sanitizeData(notes), totalAmount || 0.00, sanitizeData(billDate), sanitizeData(dueDate)]
      )

      await fetchCreateTransaction.call(this, {
        assetId,
        accountId: result.insertId,
        amount: amount || 0.00,
        action: 'ADJUSTMENT',
        balanceBefore: 0.00,
        balanceAfter: amount || 0.00,
      }, {
        userId
      })

      resolve(result.insertId)
    } catch (error) {
      console.log('fetchCreateAccount-error', error)
      reject('创建失败')
    }
  })
}

/**
 * * 用户注册
 *
 * @param {string} username 账号
 * @param {string} password 密码
 * @return {string} token字符串
 * @author Colin
 */
export const fetchRegister = async function(params) {
  return new Promise(async (resolve, reject) => {
    const { username, password } = params

    const [rows] = await pool.query(
      'SELECT * FROM users WHERE username = ?',
      [username]
    );

    if (rows.length > 0) {
      reject('用户已存在')
      return
    }

    try {
      const [result] = await pool.execute(
        `INSERT INTO users (username, password, phone, nickname, avatar, status, createdAt, updatedAt)
        VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())`,
        [username, md5(password + import.meta.env.VITE_SALT), '', '', '', true]
      )

      const token = createToken(result.insertId, username)

      resolve(token)
    } catch (error) {
      console.log('fetchRegister-error', error)
      reject('注册失败')
    }
  })
}
/**
 * * 用户登录验证
 *
 * @param {string} username 账号
 * @param {string} password 密码
 * @return {string} token字符串
 * @author Colin
 */
export const fetchLogin = async function(params) {
  return new Promise(async (resolve, reject) => {
    try {
      const { username, password } = params

      // 1. 查询数据库中的用户
      const [rows] = await pool.query(
        'SELECT * FROM users WHERE username = ?',
        [username]
      );
      // 2. 检查用户是否存在
      if (rows.length === 0) {
        return null
      }

      const user = rows[0];

      // 3. 验证密码 (假设密码是明文存储，实际应用中应该使用加密)
      if (user.password !== md5(password + import.meta.env.VITE_SALT)) {
        return null
      }

      const token = createToken(rows[0].id, username)

      resolve(token)

    } catch (error) {
      console.log('fetchLogin-error', error)
      reject('登录失败')
    }
  })
}
/**
 * 创建交易记录的异步函数
 * @param {Object} params - 交易参数对象
 * @param {number} params.assetId - 资产ID
 * @param {number} params.accountId - 账户ID
 * @param {number} params.relatedAccountId - 关联账户ID
 * @param {number} [params.amount=0.00] - 交易金额，默认为0.00
 * @param {string} params.action - 交易动作
 * @param {number} params.balanceBefore - 交易前余额
 * @param {number} params.balanceAfter - 交易后余额
 * @param {string} params.notes - 交易备注
 * @returns {Promise<number>} 返回插入记录的ID
 */
export const fetchCreateTransaction = function(params, options = {}) {
  return new Promise(async (resolve, reject) => {
    const { assetId, accountId, relatedAccountId, amount = 0.00, action, balanceBefore, balanceAfter, notes } = params
    const { userId } = this
    const { conn } = options   // 支持事务连接

    try {
      const executor = conn || pool  // 优先用事务里的连接
      const [result] = await executor.execute(
        `INSERT INTO transactions
          (userId, assetId, accountId, relatedAccountId, amount, action, balanceBefore, balanceAfter, notes)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          userId,
          assetId,
          accountId,
          sanitizeData(relatedAccountId),
          amount,
          action,
          balanceBefore,
          balanceAfter,
          sanitizeData(notes)
        ]
      )

      resolve(result.insertId)
    } catch (error) {
      console.log('fetchCreateTransaction-error', error)
      reject('创建失败')
    }
  })
}

export const fetchTransferBalance = function(params) {
  return new Promise(async (resolve, reject) => {
    let { amount, rollIn, rollOut, date, notes } = params
    rollIn = rollIn !== undefined ? Number(rollIn) : null
    rollOut = rollOut !== undefined ? Number(rollOut) : null

    const { userId } = this
    const conn = await pool.getConnection()

    try {
      await conn.beginTransaction()

      let rollOutBalanceBefore = 0
      let rollOutBalanceAfter = 0
      let rollInBalanceBefore = 0
      let rollInBalanceAfter = 0
      let rollOutAssetId = null
      let rollInAssetId = null
      let rollOutAssetType = null
      let rollInAssetType = null

      // ========= 1. 处理转出账户 =========
      if (rollOut && rollOut !== 0) {
        const [rows] = await conn.execute(
          `SELECT a.amount, a.assetId, ast.type
           FROM accounts a
           JOIN assets ast ON a.assetId = ast.id
           WHERE a.id = ? AND a.userId = ? FOR UPDATE`,
          [rollOut, userId]
        )

        if (rows.length === 0) throw new Error("转出账户不存在")

        rollOutBalanceBefore = Number(rows[0].amount)
        rollOutAssetId = rows[0].assetId
        rollOutAssetType = rows[0].type

        if (rollOutBalanceBefore < amount) throw new Error("转出账户余额不足")
        // 负债账户转出：余额增加（负债增加）
        rollOutBalanceAfter = rollOutBalanceBefore - amount

        await conn.execute(
          `UPDATE accounts SET amount = ? WHERE id = ?`,
          [rollOutBalanceAfter, rollOut]
        )
      }

      // ========= 2. 处理转入账户 =========
      if (rollIn && rollIn !== 0) {
        const [rows] = await conn.execute(
          `SELECT a.amount, a.assetId, ast.type
           FROM accounts a
           JOIN assets ast ON a.assetId = ast.id
           WHERE a.id = ? AND a.userId = ? FOR UPDATE`,
          [rollIn, userId]
        )

        if (rows.length === 0) throw new Error("转入账户不存在")

        rollInBalanceBefore = Number(rows[0].amount)
        rollInAssetId = rows[0].assetId
        rollInAssetType = rows[0].type

        rollInBalanceAfter = rollInBalanceBefore + amount

        await conn.execute(
          `UPDATE accounts SET amount = ? WHERE id = ?`,
          [rollInBalanceAfter, rollIn]
        )
      }

      // 内部账户之间的转账（使用TRANSFER类型）
      if (rollOut && rollOut !== 0 && rollIn && rollIn !== 0) {
        // 转出记录
        await fetchCreateTransaction.call(this, {
          assetId: rollOutAssetId,
          accountId: rollOut,
          relatedAccountId: rollIn,
          amount: amount,
          action: 'TRANSFER',
          balanceBefore: rollOutBalanceBefore,
          balanceAfter: rollOutBalanceAfter,
          notes: notes,
          transactionDate: date
        }, { userId, conn })

        // 转入记录
        await fetchCreateTransaction.call(this, {
          assetId: rollInAssetId,
          accountId: rollIn,
          relatedAccountId: rollOut,
          amount: amount,
          action: 'TRANSFER',
          balanceBefore: rollInBalanceBefore,
          balanceAfter: rollInBalanceAfter,
          notes: notes,
          transactionDate: date
        }, { userId, conn })
      }
      // 外部转入到内部账户（视为收入）
      else if ((rollOut === 0 || rollOut === null) && rollIn && rollIn !== 0) {
        await fetchCreateTransaction.call(this, {
          assetId: rollInAssetId,
          accountId: rollIn,
          relatedAccountId: null,
          amount: amount,
          action: 'INCOME',
          balanceBefore: rollInBalanceBefore,
          balanceAfter: rollInBalanceAfter,
          notes: notes,
          transactionDate: date
        }, { userId, conn })
      }
      // 内部账户转到外部（视为支出）
      else if (rollOut && rollOut !== 0 && (rollIn === 0 || rollIn === null)) {
        await fetchCreateTransaction.call(this, {
          assetId: rollOutAssetId,
          accountId: rollOut,
          relatedAccountId: null,
          amount: amount,
          action: 'EXPENSE',
          balanceBefore: rollOutBalanceBefore,
          balanceAfter: rollOutBalanceAfter,
          notes: notes,
          transactionDate: date
        }, { userId, conn })
      }
      // 外部到外部（不记录交易流水）

      await conn.commit()
      resolve(true)

    } catch (error) {
      await conn.rollback()
      console.log('fetchTransferBalance-error', error)
      reject(error.message || '转账失败')
    } finally {
      conn.release()
    }
  })
}
